#import "FlutterPluginGdmapPlugin.h"
#import "MyConstant.h"
#import <AMapFoundationKit/AMapFoundationKit.h>
#import <AMapSearchKit/AMapSearchKit.h>
#import "GdmapPoiFlutterStreamManager.h"
#import "MAGeometry.h"
#import "AMapViewFactory.h"
#import "AMapNaviFactory.h"
#import "AMapPolygonsFactory.h"

static NSObject <FlutterPluginRegistrar> *_registrar;

@interface FlutterPluginGdmapPlugin ()<AMapLocationManagerDelegate,FlutterStreamHandler,AMapSearchDelegate>{
    
    NSMutableString *mLocation;//定位信息json字符串
    NSMutableDictionary *locationDic;//最新定位信息存储字典
    
    AMapSearchAPI * _search;//搜索对象
    CLLocation * _currentLocation;//坐标位置
}

@property (nonatomic, strong) FlutterEventSink eventSink;//地址变化

@end

@implementation FlutterPluginGdmapPlugin


+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
    [AMapServices sharedServices].enableHTTPS = YES;
    _registrar = registrar;
    
    //接收flutter发送的数据
    FlutterMethodChannel *channel = [FlutterMethodChannel
             methodChannelWithName:[AMAP_CHANNEL_NAME stringByAppendingString:@"/location"]
                  binaryMessenger:[registrar messenger]];
    
    FlutterPluginGdmapPlugin* instance = [[FlutterPluginGdmapPlugin alloc] init];
    [registrar addMethodCallDelegate:instance channel:channel];
   
    
    //定位发送变化时实时通知flutter
    FlutterEventChannel *eventChannel = [FlutterEventChannel
             eventChannelWithName:[AMAP_CHANNEL_NAME stringByAppendingString:@"/locationChanged"]
                 binaryMessenger:[registrar messenger]];
    [eventChannel setStreamHandler:instance];
    
    
    //poi结果通知flutter
    FlutterEventChannel *poiEventChannel = [FlutterEventChannel
             eventChannelWithName:[AMAP_CHANNEL_NAME stringByAppendingString:@"/getPoiList"]
                 binaryMessenger:[registrar messenger]];
    [poiEventChannel setStreamHandler:[[GdmapPoiFlutterStreamManager sharedInstance] streamHandler]];
    
    //注册地图控件
    [_registrar registerViewFactory:[[AMapViewFactory alloc] init]
                                withId:[AMAP_CHANNEL_NAME stringByAppendingString:@"/AMapView"]];
    
    //注册导航控件
    [_registrar registerViewFactory:[[AMapNaviFactory alloc] init]
                                withId:[AMAP_CHANNEL_NAME stringByAppendingString:@"/AMapNaviView"]];
    
    //注册围栏控件
    [_registrar registerViewFactory:[[AMapPolygonsFactory alloc] init]
                                withId:[AMAP_CHANNEL_NAME stringByAppendingString:@"/AMapPolygonView"]];
    
    [instance initLocation];
    [instance initSearch];
}

- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
    if ([@"setKey" isEqualToString:call.method]) {
        //设置高德key
        NSString *key = call.arguments[@"key"];
        [AMapServices sharedServices].apiKey = key;
        result(@"key设置成功");
    }else if ([@"inspectionGPS" isEqualToString:call.method]) {
        //检查GPS开启状态
        BOOL isOpen=[self isOPenLocation];
        if(isOpen==YES){
            result([NSNumber numberWithBool:YES]);
        }else{
            result([NSNumber numberWithBool:NO]);
        }
    }else if ([@"startLocation" isEqualToString:call.method]) {
        //启动定位
        [self.locationManager startUpdatingLocation];
    }else if ([@"stopLocation" isEqualToString:call.method]) {
        //停止定位
        [self.locationManager stopUpdatingLocation];
    }else if ([@"getLocation" isEqualToString:call.method]) {
        //单次获取最新的定位数据
        result(mLocation);
    }else if ([@"startService" isEqualToString:call.method]) {
        //启动前台服务
        //iOS不做操作
    }else if ([@"stopService" isEqualToString:call.method]) {
        //关闭前台服务
        //iOS不做操作
    }else if ([@"locationSearch" isEqualToString:call.method]) {
        //位置搜索
        [self getAddressSearch:call.arguments[@"address"] :[call.arguments[@"page"] intValue]];
    }else if ([@"distanceSearch" isEqualToString:call.method]) {
        //行车距离计算
//        因相应功能废弃,这里弃用~
    }else if ([@"distanceCompute" isEqualToString:call.method]) {
        //两点间直线距离计算
        NSData *startLocationData = [call.arguments[@"startLocation"] dataUsingEncoding:NSUTF8StringEncoding];
        NSDictionary *startLocationDic = [NSJSONSerialization JSONObjectWithData:startLocationData
                                                               options:NSJSONReadingMutableContainers
                                                                 error:nil];
        
        NSData *endLocationData = [call.arguments[@"endLocation"] dataUsingEncoding:NSUTF8StringEncoding];
        NSDictionary *endLocationDic = [NSJSONSerialization JSONObjectWithData:endLocationData
                                                               options:NSJSONReadingMutableContainers
                                                                 error:nil];
        
        //1.将两个经纬度点转成投影点
        MAMapPoint point1 = MAMapPointForCoordinate(CLLocationCoordinate2DMake([[startLocationDic objectForKey:@"latitude"] doubleValue],[[startLocationDic objectForKey:@"longitude"] doubleValue]));
        MAMapPoint point2 = MAMapPointForCoordinate(CLLocationCoordinate2DMake([[endLocationDic objectForKey:@"latitude"] doubleValue],[[endLocationDic objectForKey:@"longitude"] doubleValue]));
        //2.计算距离
        CLLocationDistance distance = MAMetersBetweenMapPoints(point1,point2);
        //为了保证精度
        NSString *dStr = [NSString stringWithFormat:@"%f", distance];
        NSDecimalNumber *dn = [NSDecimalNumber decimalNumberWithString:dStr];
        result([dn stringValue]);
    } else {
        result(FlutterMethodNotImplemented);
    }
}

#pragma --mark FlutterStreamHandler代理
- (FlutterError* _Nullable)onListenWithArguments:(id _Nullable)arguments eventSink:(FlutterEventSink)events {
    if (events) {
        self.eventSink  = events;
    }
    return nil;
}

// 不再需要向Flutter传递消息
- (FlutterError* _Nullable)onCancelWithArguments:(id _Nullable)arguments {
    return nil;
}

//获取registrar
+ (NSObject <FlutterPluginRegistrar> *)registrar {
    return _registrar;
}

//获取定位开启状态
- (BOOL)isOPenLocation{
    if ([CLLocationManager locationServicesEnabled] && ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorizedWhenInUse || [CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined || [CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorizedAlways)) {
        //定位功能可用
        NSLog(@"定位功能可用");
        return YES;
    }else if ([CLLocationManager authorizationStatus] ==kCLAuthorizationStatusDenied) {
        //定位不能用
        NSLog(@"定位不能用");
        return NO;
    }
    return NO;
}

//初始化定位
- (void)initLocation{
    //locationManager初始化
    self.locationManager = [[AMapLocationManager alloc] init];

    [self.locationManager setDelegate:self];

    //设置不允许系统暂停定位
    [self.locationManager setPausesLocationUpdatesAutomatically:NO];
    
    //设置允许在后台定位
    [self.locationManager setAllowsBackgroundLocationUpdates:YES];
    
    //设置允许连续定位逆地理
    [self.locationManager setLocatingWithReGeocode:YES];
}

//serach初始化
-(void)initSearch{
    _search =[[AMapSearchAPI alloc] init];
    _search.delegate=self;
}

//iOS 11及以上版本使用后台定位服务需要实现amapLocationManager:doRequireLocationAuth:代理方法
- (void)amapLocationManager:(AMapLocationManager *)manager doRequireLocationAuth:(CLLocationManager*)locationManager
{
    [locationManager requestAlwaysAuthorization];
}

//定位回调
- (void)amapLocationManager:(AMapLocationManager *)manager didUpdateLocation:(CLLocation *)location reGeocode:(AMapLocationReGeocode *)reGeocode
{
    _currentLocation=location;
    if (reGeocode){
        double accuracy = [[NSString stringWithFormat:@"%.5f", location.horizontalAccuracy] doubleValue] + 0.00001;
        double bearing  = [[NSString stringWithFormat:@"%.5f", location.course] doubleValue] + 0.00001;
        double speed    = [[NSString stringWithFormat:@"%.5f", location.speed] doubleValue] + 0.00001;
          //获取时间戳 只有10位 需要*1000
          NSTimeInterval timeInterval = [[NSDate date] timeIntervalSince1970];
          locationDic = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                               [NSNumber numberWithDouble:location.coordinate.longitude],@"longitude",
                                               [NSNumber numberWithDouble:location.coordinate.latitude],@"latitude",
                                               [NSNumber numberWithDouble:location.altitude],@"altitude",
                                               [NSNumber numberWithDouble:accuracy],@"accuracy",
                                               [NSNumber numberWithDouble:bearing],@"bearing",
                                               [NSNumber numberWithDouble:speed],@"speed",
                                               [NSNumber numberWithInt:1],@"locationType",//ios没有这个参数
                                               reGeocode.country,@"country",
                                               reGeocode.province,@"province",
                                               reGeocode.city,@"city",
                                               reGeocode.district,@"district",
                                               reGeocode.street,@"street",
                                               reGeocode.citycode,@"cityCode",
                                               reGeocode.adcode,@"adCode",
                                               reGeocode.AOIName,@"aoiName",
                                               reGeocode.formattedAddress,@"address",
                                               [NSNumber numberWithLong:(timeInterval*1000)],@"time",
                                               nil];
          
          NSData *data=[NSJSONSerialization dataWithJSONObject:locationDic options:NSJSONWritingPrettyPrinted error:nil];
          mLocation=[[NSMutableString alloc]initWithData:data encoding:NSUTF8StringEncoding];
          NSLog(@"定位json字符串:%@", mLocation);
        if (self.eventSink){
            self.eventSink(mLocation);
        }
      }
}

///位置搜索
- (void)getAddressSearch:(NSString *) address :(NSInteger) page{
    AMapPOIKeywordsSearchRequest  *request=[[AMapPOIKeywordsSearchRequest alloc] init];
    
    request.keywords =address;
    request.types = @"汽车服务|汽车销售|汽车维修|摩托车服务|餐饮服务|购物服务|生活服务|体育休闲服务|医疗保健服务|住宿服务|风景名胜|商务住宅|政府机构及社会团体|科教文化服务|交通设施服务|金融保险服务|公司企业|道路附属设施|地名地址信息|公共设施|通行设施";
    request.page = page;
    request.offset = 20;
    request.city = [locationDic objectForKey:@"cityCode"];
    if (!address.length) {
        NSLog(@"搜索关键字为空就搜索周边");
        request.location=[AMapGeoPoint locationWithLatitude:_currentLocation.coordinate.latitude longitude:_currentLocation.coordinate.longitude];
    }
    [_search AMapPOIKeywordsSearch:request];
}

/* POI 搜索回调. */
- (void)onPOISearchDone:(AMapPOISearchBaseRequest *)request response:(AMapPOISearchResponse *)response
{
    NSLog(@"搜索回调~~~~：%i",response.pois.count);
    if (response.pois.count == 0){
        [[GdmapPoiFlutterStreamManager sharedInstance] streamHandler].eventSink(@"");
    }else{
        NSMutableArray *poiArr = [[NSMutableArray alloc]init];
        NSMutableDictionary *poiDic;
        for (AMapPOI *pois in response.pois) {
            poiDic = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                           pois.name,@"name",
                                           pois.address,@"address",
                                           [NSNumber numberWithDouble:pois.location.longitude],@"longitude",
                                           [NSNumber numberWithDouble:pois.location.latitude],@"latitude",
                                           pois.city,@"city",
                                           @(pois.distance),@"distance",
                                                 nil];
            [poiArr addObject:poiDic];
        }
        NSData *data=[NSJSONSerialization dataWithJSONObject:poiArr options:NSJSONWritingPrettyPrinted error:nil];
        NSString *poiStr=[[NSMutableString alloc]initWithData:data encoding:NSUTF8StringEncoding];
        NSLog(@"搜索json字符串:%@", poiStr);
        [[GdmapPoiFlutterStreamManager sharedInstance] streamHandler].eventSink(poiStr);
    }
}


@end
